package com.feiwo.nonego.rpc.codec;

import com.feiwo.nonego.rpc.common.util.SerializationUtils;
import com.feiwo.nonego.rpc.protocol.RpcProtocol;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

import java.nio.charset.StandardCharsets;

/**
 * RPC 消息编码器
 *
 * @author feiwo 2025-08-05
 */
public class RpcEncoder extends MessageToByteEncoder<RpcProtocol<Object>> implements RpcCodec{
    /**
     * 编码RPC协议消息到字节缓冲区
     *
     * @param context 通道处理上下文，用于处理I/O事件和操作
     * @param msg RPC协议消息对象，包含头部信息和消息体数据
     * @param byteBuf 字节缓冲区，用于存储编码后的字节数据
     * @throws Exception 序列化过程中可能抛出的异常
     */
    @Override
    protected void encode(ChannelHandlerContext context, RpcProtocol<Object> msg, ByteBuf byteBuf) throws Exception {
        // 写入消息头部信息
        var header = msg.getHeader();
        byteBuf.writeShort(header.getMagic());
        byteBuf.writeByte(header.getMsgType());
        byteBuf.writeByte(header.getStatus());
        byteBuf.writeLong(header.getMsgId());

        // 序列化消息体数据
        var serializationType = header.getSerializationType();
        var serialization = getSerialization(serializationType);
        byteBuf.writeBytes(SerializationUtils.getSerializationType(serializationType).getBytes(StandardCharsets.UTF_8));
        var data = serialization.serialize(msg.getBody());
        byteBuf.writeInt(data.length);
        byteBuf.writeBytes(data);
    }

}
